import base64
import hashlib
import random
import re

from Crypto.Cipher import AES

from utils.read_files_tools.read_extract_yaml import ReadYamlData


class DebugTalk:
    def __init__(self):
        self.read = ReadYamlData()

    def get_baseurl(self):
        """ 主机地址 """
        from config.operationConfig import OperationConfig
        conf = OperationConfig()
        url = conf.get_section_for_data('api_envi', 'host')
        return url

    def get_headers(self, params_type):
        """
        获取请求头
        :param params_type: 参数类型 如'data'或'json'
        :return:
        """
        headers_mapping = {
            'data': {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'},
            'json': {'Content-Type': 'application/json;charset=UTF-8'},
            'params': {'Content-Type': 'text/plain;charset=UTF-8'}
        }
        headers = headers_mapping.get(params_type)
        if headers is None:
            raise ValueError('不支持其他类型的请求头设置！')
        return headers

    def get_extract_data(self, node_name, randoms=None) -> str:
        """
        热加载：获取extract.yaml数据，首先判断randoms是否为数字类型，如果不是就获取下一个node节点的数据
        :param node_name: extract.yaml文件中的key值
        :param randoms: int类型，0：随机读取；-1：读取全部，返回字符串形式；-2：读取全部，返回列表形式；其他根据列表索引取值，取第一个值为1，第二个为2，以此类推;
        :return:
        """
        data = self.read.get_extract_yaml(node_name)
        if randoms is not None and bool(re.compile(r'^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$').match(randoms)):
            randoms = int(randoms)
            data_value = {
                randoms: self.get_extract_order_data(data, randoms),
                0: random.choice(data),
                -1: ','.join(data),
                -2: ','.join(data).split(','),
            }
            data = data_value[randoms]
        else:
            data = self.read.get_extract_yaml(node_name, randoms)
        return data

    def get_extract_order_data(self, data, randoms):
        """ 获取extract.yaml数据，不为0、-1、-2，则按顺序读取文件key的数据 """
        if randoms not in [0, -1, -2]:
            return data[randoms - 1]

    def aes_encryption(self, data, key):
        """
        AES-ECB模式 加密
        :param data: 需要加密的数据
        :param key: 密钥
        :return:
        """
        while len(data) % 16 != 0:
            data += (16 - len(data) % 16) * chr(16 - len(data) % 16)
            data = str.encode(data)
            aes = AES.new(str.encode(key), AES.MODE_ECB)
            encrypted_text = str(base64.encodebytes(aes.encrypt(data)), encoding='utf8').replace('\n', '')
            return encrypted_text

    def aes_encryption_key(self, data):
        """
        AES-ECB模式 加密 yaml文件使用，不需要输入key：password: ${aes_encryption_key(admin)}
        :param data: 需要加密的数据
        :return:
        """
        # key值 需要从上个接口提取到extract.yaml文件，然后从extract.yaml文件获取，提取字段要为“key”
        key = self.get_extract_data('key')

        while len(data) % 16 != 0:
            data += (16 - len(data) % 16) * chr(16 - len(data) % 16)
            data = str.encode(data)
            aes = AES.new(str.encode(key), AES.MODE_ECB)
            encrypted_text = str(base64.encodebytes(aes.encrypt(data)), encoding='utf8').replace('\n', '')
            return encrypted_text

    def aes_decryption(self, data, key):
        """
        AES-ECB模式 解密
        :param data: 需要解密的数据
        :param key: 密钥
        :return:
        """
        try:
            aes = AES.new(str.encode(key), AES.MODE_ECB)
            decrypted_text = aes.decrypt(base64.decodebytes(bytes(data, encoding='utf8'))).decode("utf8")
            decrypted_text = decrypted_text[:-ord(decrypted_text[-1])]
            return decrypted_text
        except Exception as e:
            pass

    def md5_encryption(self, data):
        """
        参数MD5加密
        :param data: 需要加密的数据
        :return:
        """
        if data is None:
            enc_data = ''
            return enc_data  # 返回为小写，需要转大写后面添加.upper
        else:
            enc_data = hashlib.md5()
            enc_data.update(data.encode(encoding='utf-8'))
            return enc_data.hexdigest()

    def sha1_encryption(self, data):
        """
        参数sha1加密
        :param data: 需要加密的数据
        :return:
        """
        enc_data = hashlib.sha1()
        enc_data.update(data.encode(encoding='utf-8'))
        return enc_data.hexdigest()

    def base64_encryption(self, data):
        """
        base64加密
        :param data: 需要加密的数据
        :return:
        """
        base_data = data.encode("utf-8")
        enc_data = base64.encode(base_data)
        return enc_data
